import kline

K_TYPE_UP = "A"  # 上涨
K_TYPE_DOWN = "B"  # 下跌
K_TYPE_EXPAND_N = "C"  # 正常板块扩张
K_TYPE_EXPAND_UP = "D"  # 上扩张
K_TYPE_EXPAND_DOWN = "E"  # 下扩张
K_TYPE_RETRACT_N = "F"  # 正常收敛
K_TYPE_RETRACT_UP = "G"  # 上收敛
K_TYPE_RETRACT_DOWN = "H"  # 下收敛
K_TYPE_SMOOTH_N = "I"  # 正常平稳
K_TYPE_JUMP_UP = "J"  # 上跳空
K_TYPE_JUMP_DOWN = "K"  # 下跳空
K_TYPE_UNKNOWN = "Z"  # 未知


# 根据两个K线判断规则,type=类型，direction=方向 1:向上 2:向下 3:平
def judge2k(k1, k2):
    res={}
    # 判断上涨
    if k1.low < k2.low and k1.high < k2.high and k2.low < k1.high:
        res['type']=K_TYPE_UP
        res['direction']=1
    # 判断下跌
    elif k1.high > k2.high and k1.low > k2.low and k2.high > k1.low:
        res['type']=K_TYPE_DOWN
        res['direction']=2
    # 判断正常板块扩张
    elif k1.high < k2.high and k2.low < k1.low:
        res['type']=K_TYPE_EXPAND_N
        res['direction']=3
    # 判断上扩张
    elif k1.high < k2.high and k2.low == k1.low:
        res['type']=K_TYPE_EXPAND_UP
        res['direction']=3
    # 判断下扩张
    elif k1.low > k2.low and k2.high == k1.high:
        res['type']=K_TYPE_EXPAND_DOWN
        res['direction']=3
    # 判断正常收敛
    elif k1.high > k2.high and k2.low > k1.low:
        res['type']=K_TYPE_RETRACT_N
        res['direction']=3
    # 判断上收敛
    elif k1.high == k2.high and k2.low > k1.low:
        res['type']=K_TYPE_RETRACT_UP
        res['direction']=3
    # 判断下收敛
    elif k1.low == k2.low and k2.high < k1.high:
        res['type']=K_TYPE_RETRACT_DOWN
        res['direction']=3
    # 判断正常平稳
    elif k1.low == k2.low and k2.high == k1.high:
        res['type']=K_TYPE_SMOOTH_N
        res['direction']=3
    # 判断上跳空
    elif k2.low > k1.high:
        res['type']=K_TYPE_JUMP_UP
        res['direction']=1
    # 判断下跳空
    elif k2.high < k1.low:
        res['type']=K_TYPE_JUMP_DOWN
        res['direction']=2
    # 未知
    else:
        res['type']=K_TYPE_UNKNOWN
        res['direction']=3
        
    # print('对比结果：',res)
    return res

# 根据K线列表返回形成的折叠信息
def get_fold(k_list):
    res = []
    line_start=-1#折线开始位置
    line_end=0#折线结束位置
    line_direction=0#当前走势的方向
    line_max=0#折线的最高点
    line_min=0#折线的最低点
    line_num=0#折线中包含K线数量
    line_jump_time=0#跳空次数
    line = kline.Kline(line_start, line_end, line_direction, line_max, line_min, line_num, line_jump_time)
    if len(k_list) < 2:
        return res
    else:
        for i in range(len(k_list) - 2):
            k1 = k_list.iloc[i]
            k2 = k_list.iloc[i + 1]
            rule = judge2k(k1, k2)
            
            line_num=line_num+1
            #初始情况,还没有方向
            if line_direction == 0 :
                #记录开始K线位置
                if line_start == -1: 
                    line_start = i
                    line_stime = k1['day']
                #判断方向
                if rule['direction'] != 3:
                    line_direction = rule['direction']
                    line_max = float(k2.high)
                    line_min = float(k2.low)
            #相同方向,判断最高，最低点
            if line_direction == rule['direction']:
                #上扬
                if rule['direction'] == 1:
                    line_max = max(line_max, float(k2.high))
                #下跌
                if rule['direction'] == 2:
                    line_min = min(line_min, float(k2.low))
                    
            
            #相反方向，产生折叠
            if line_direction != rule['direction'] and line_direction != 0 and rule['direction'] !=3:
                
                #将之前的折线记录到结果中
                line_end = i
                line_num=line_num-1
                line.line_start = line_start
                line.line_end = line_end
                line.line_direction = line_direction
                line.line_max = line_max
                line.line_min = line_min
                line.line_jump_time = line_jump_time
                line.line_num = line_num
                line.line_stime = line_stime
                line.line_endtime = k2['day']
                res.append(line)
                
                print('出现转折：',i,vars(line))
                
                #将新折线信息初始化
                line_start = i
                line_stime = k1['day']
                line_direction = rule['direction']
                line_jump_time = 0
                line_num = 1
                line_max = float(k2.high)
                line_min = float(k2.low)
                line = kline.Kline(line_start, line_end, line_direction, line_max, line_min, line_num, line_jump_time)
                
            #判断跳空
            if rule['type'] in [K_TYPE_JUMP_UP, K_TYPE_JUMP_DOWN]:
                line_jump_time += 1    
                
            #判断最后一根K线
            if i == len(k_list) - 3:
                line_end = i + 1
                line.line_start = line_start
                line.line_end = line_end
                line.line_direction = line_direction
                line.line_max = line_max
                line.line_min = line_min
                line.line_jump_time = line_jump_time
                line.line_num = line_num
                line.line_endtime = k2['day']
                res.append(line)
    return res

#根据列表判断规则
def judge_k_list(k_list):
    res={}
    line_list = get_fold(k_list)
    
    for line in line_list:
        print("折线结果:",vars(line))
        
    if len(line_list) < 3:
        return res

# #根据列表判断规则
# def judge_k_list(k_list):
#     res = {}
#     waveStart = 0 #波动开始的位置
#     waveEnd = 0 #波动结束的位置
#     waveSdirection = 0 #波动开始的方向
#     ifzs = 0 #是否存在中枢
#     direction = ''#当前走势的方向
#     waveNum=0 #波动的折叠次数
#     waveTotal=0 #本次中枢的总K线数量
#     waveMin=0 #波动最小值
#     waveMax=0 #波动最大值
#     waveRangeMin=0 #波动范围最小值
#     waveRangeMax=0 #波动范围最大值
#     waveRangeMin_p1=0 #第一次波动范围最小值
#     waveRangeMax_p1=0 #第一次波动范围最大值
    
#     if len(k_list) < 2:
#         return K_TYPE_UNKNOWN
#     else:
#         for i in range(len(k_list) - 1):
#             k1 = k_list.iloc[i]
#             k2 = k_list.iloc[i + 1]
#             rule = judge2k(k1, k2)
#             #如果暂时还没有方向，认为刚开始
#             if direction == '' and rule['direction'] != 3:
#                 direction = rule['direction']
#                 waveStart = k1['day']
#                 waveSdirection = rule['direction']
                
#             if direction == rule['direction']:#方向相同
#                 waveTotal += 1
#                 if rule['direction'] == 1:#向上
#                     #如果还没有形成中枢
#                     if ifzs == 0:
#                         #判断有几条折叠，
#                         # 0时=只能刚开始，并且为上扬阶段，
#                         if waveNum == 0:
#                             waveRangeMax = k2.high
#                             waveMax = k2.high
#                             waveprangemax_p1 = k2.high
#                         # 1时=只能是下->上，无需判断
#                         # if waveNum == 1:
#                         # 2时=上->下->上，判断是否形成中枢,如果此时最低点高于震荡的最低点，则形成中枢
#                         if waveNum == 2:
#                             if k2.high > waveRangeMin:
#                                 ifzs = 1
#                     #判断震荡区间最高点,这里先不用考虑是否形成中枢
#                     if waveNum <= 2:
#                         if k2.high > waveRangeMax:
#                             waveRangeMax = waveprangemax_p1
#                         if k2.high < waveRangeMax:
#                             waveRangeMax = k2.high
#                     #判断整体中枢最高点
#                     if k2.high > waveMax:
#                         waveMax = k2.high    
#                     #如果已经形成中枢
#                     else:
#                         #判断是否结束
                        
                    
                        
#                 else :#向下
#                     #如果还没有形成中枢，则记录波动范围值
#                     if ifzs == 0:
#                         #判断有几条折叠，
#                         # 0时=只能刚开始，并且为下跌阶段，
#                         if waveNum == 0:
#                             waveRangeMin = k2.low
#                             waveMin = k2.low
#                             waveprangemin_p1 = k2.low
#                         # 1时=只能是上->下 ，无需判断
#                         # if waveNum == 1:
#                         # 2时=下->上->下，判断是否形成中枢,如果此时最高点低于震荡的最高点，则形成中枢
#                         if waveNum == 2:
#                             if k2.low < waveRangeMax:
#                                 ifzs = 1

#                     if waveNum <= 2:
#                     #判断震荡区间最低点
#                         if k2.low < waveRangeMin:
#                             waveRangeMin = waveprangemin_p1
#                         if k2.low > waveRangeMin:
#                             waveRangeMin = k2.low
#                     #判断整个中枢最低点
#                         if k2.low < waveMin:
#                             waveMin = k2.low 
#             else:#方向不同,视为转折              
#                 waveNum += 1             
#                 #如果方向向上0
#                 if rule['direction'] == 1:
                                     
                            
                            
                                
                            
                         
                        
                
#         return res
